package com.newlink.building.userinfo.activity

import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Environment
import android.provider.MediaStore
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.FileProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.newlink.building.common_base.base.NL_BaseMvpActivity
import com.newlink.building.common_base.ext.showToast
import com.newlink.building.common_base.ext.showToastLong
import com.newlink.building.common_base.model.bean.DoorData
import com.newlink.building.common_base.model.bean.FeedbackRequest
import com.newlink.building.common_base.widget.SpaceItemDecoration
import com.newlink.building.activities.call.adapter.Module_Phone_DtmfAdapter
import com.newlink.building.common_base.utils.logDebug
import com.newlink.building.userinfo.R
import com.newlink.building.userinfo.adapter.Module_UserInfo_ImageAdapter
import com.newlink.building.userinfo.databinding.ActivityFeedbackBinding
import com.newlink.building.userinfo.mvp.Module_UserInfo_FeedbackPresenter
import com.newlink.building.userinfo.mvp.contract.Module_UserInfo_FeedbackContract
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date


/**
 * Created by xiaodong on 2024/11/5.
 */
class Module_UserInfo_FeedbackActivityNL : NL_BaseMvpActivity<Module_UserInfo_FeedbackContract.View, Module_UserInfo_FeedbackContract.Presenter>(),
    Module_UserInfo_FeedbackContract.View {

    private val REQUEST_IMAGE_CAPTURE: Int = 1
    private val REQUEST_IMAGE_GALLERY: Int = 2
    private var imageUri: Uri? = null
    private var currentPhotoPath: String? = null
    private lateinit var mBinding: ActivityFeedbackBinding
    private var imageAdapter: Module_UserInfo_ImageAdapter? = null
    private val imageUriList: MutableList<Uri> = mutableListOf()
    private val MAX_IMAGE_COUNT = 5 // 最大选择图片数量
    override fun createPresenter(): Module_UserInfo_FeedbackContract.Presenter = Module_UserInfo_FeedbackPresenter()

    override fun attachLayoutRes(): View? {
        mBinding = ActivityFeedbackBinding.inflate(layoutInflater)
        return mBinding.root
    }

    override fun initData() {
    }

    override fun initView() {
        mBinding.titleBar.tvTitleBarRight.visibility = View.VISIBLE
        mBinding.titleBar.tvTitleBarCenter.text = getString(R.string.settings_help_feedback)
        imageAdapter = Module_UserInfo_ImageAdapter(imageUriList)
        mBinding.recyclerView.run {
            adapter = imageAdapter
            addItemDecoration(SpaceItemDecoration(this@Module_UserInfo_FeedbackActivityNL, 5))
        }
        mBinding.ivAddPicture.setOnClickListener {
            showPickPictureDialog()
        }
        imageAdapter?.setOnItemClickListener(object : Module_UserInfo_ImageAdapter.OnItemClickListener {

            override fun deleteClick(view: View, position: Int) {
                imageUriList.removeAt(position)
                imageAdapter?.notifyDataSetChanged()
                if (imageUriList.size < 5) {
                    mBinding.rlAddPicture.visibility = View.VISIBLE
                }
            }

            override fun itemClick(view: View, position: Int) {
            }

        })

        mBinding.btnSubmit.setOnClickListener {
            val deviceType = mBinding.etDeviceType.text.toString()
            val describe = mBinding.etDescribe.text.toString()
            val contact = mBinding.tvContact.text.toString()
            if (deviceType.isEmpty()) {
                showToast(
                    String.format(
                        getString(R.string.feedback_params_empty),
                        getString(R.string.feedback_device_type)
                    )
                )
                return@setOnClickListener
            }
            if (describe.isEmpty()) {
                showToast(
                    String.format(
                        getString(R.string.feedback_params_empty),
                        getString(R.string.feedback_problem_desc)
                    )
                )
                return@setOnClickListener
            }
            if (contact.isEmpty()) {
                showToast(
                    String.format(
                        getString(R.string.feedback_params_empty),
                        getString(R.string.feedback_contact_info)
                    )
                )
                return@setOnClickListener
            }
            submitFeedback(deviceType, describe, contact)
        }



        mBinding.etDescribe.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun afterTextChanged(p0: Editable?) {
                mBinding.tvWordNumber.text = "${mBinding.etDescribe.text.length}/500"
            }
        })
    }

    private fun createFeedbackRequestParts(
        deviceType: String,
        describe: String,
        contact: String,
    ): List<MultipartBody.Part> {
        val parts = mutableListOf<MultipartBody.Part>()
        val title = RequestBody.create("text/plain".toMediaTypeOrNull(), deviceType)
        parts.add(MultipartBody.Part.createFormData("deviceType", null, title))

        val description = RequestBody.create("text/plain".toMediaTypeOrNull(), describe)
        parts.add(MultipartBody.Part.createFormData("description", null, description))

        val contactInfo = RequestBody.create("text/plain".toMediaTypeOrNull(), contact)
        parts.add(MultipartBody.Part.createFormData("contactInfo", null, contactInfo))
        return parts
    }

    private fun submitFeedback(
        deviceType: String,
        description: String,
        contactInfo: String,
    ) {
        showLoading()
        lifecycleScope.launch(Dispatchers.IO) {
            var parts = mutableListOf<MultipartBody.Part>()
            parts.addAll(createFeedbackRequestParts(deviceType, description, contactInfo))
            parts.addAll(parseImageParts())
            MainScope().launch(Dispatchers.Main) {
                hideLoading()
                mPresenter?.sendFeedBack(
                    accessToken,
                    FeedbackRequest(
                        deviceType = deviceType,
                        description = description,
                        contactInfo = contactInfo
                    ),
                    parts
                )
            }
        }
    }

    private fun parseImageParts(): List<MultipartBody.Part> {
        val parts = mutableListOf<MultipartBody.Part>()

        for (item in imageUriList) {

            // 获取图片的输入流
            val inputStream = contentResolver.openInputStream(item)
            // 解码图片为 Bitmap
            val originalBitmap = BitmapFactory.decodeStream(inputStream)
            inputStream?.close()
            // 压缩图片
            val compressedBitmap = compressAndEncodeImage(originalBitmap)

            // 将压缩后的 Bitmap 转换为字节数组
            val byteArrayOutputStream = ByteArrayOutputStream()
            compressedBitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream)
            val byteArray = byteArrayOutputStream.toByteArray()
            byteArrayOutputStream.close()

            // 创建 RequestBody
            val requestBody = RequestBody.create("image/jpeg".toMediaTypeOrNull(), byteArray)

            // 创建 MultipartBody.Part
            val body: MultipartBody.Part =
                MultipartBody.Part.createFormData(
                    "photos",
                    getFileName(item.path.orEmpty()),
                    requestBody
                )

            parts.add(body)
        }

        return parts
    }

    private fun getFileName(urlPath: String): String {
        var filePath = ""
        if (urlPath.contains("/")) {
            filePath = urlPath.split("/").last()
        }
        logDebug<Module_UserInfo_FeedbackActivityNL>("urlPath:$urlPath filePath:$filePath")
        return filePath
    }

    private fun compressAndEncodeImage(bitmap: Bitmap): Bitmap {
        var quality = 100
        var byteArrayOutputStream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream)
        logDebug<Module_UserInfo_FeedbackActivityNL>("图片压缩前:${byteArrayOutputStream.toByteArray().size / 1024} kb")

        while (byteArrayOutputStream.toByteArray().size > 500 * 1024 && quality > 0) {
            quality -= 5
            byteArrayOutputStream = ByteArrayOutputStream()
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream)
        }

        val compressedImage = byteArrayOutputStream.toByteArray()
        val decodeByteArray =
            BitmapFactory.decodeByteArray(compressedImage, 0, compressedImage.size)

        logDebug<Module_UserInfo_FeedbackActivityNL>("图片压缩后:${byteArrayOutputStream.toByteArray().size / 1024} kb quality:$quality")
        return decodeByteArray
    }


    private fun openImagePicker() {
        val intent = Intent(Intent.ACTION_PICK)
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*")
        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
        intent.setAction(Intent.ACTION_GET_CONTENT)
        startActivityForResult(
            Intent.createChooser(intent, "选择图片"), REQUEST_IMAGE_GALLERY
        )
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            imageUri?.let {
                imageUriList.add(it)
            }
        }

        if (requestCode == REQUEST_IMAGE_GALLERY && resultCode == RESULT_OK) {
            if (data?.clipData != null) {
                val availableSlots = MAX_IMAGE_COUNT - imageUriList.size
                var count =
                    if (data.clipData!!.itemCount > availableSlots) availableSlots else data.clipData!!.itemCount
                for (i in 0 until count) {
                    val imageUri = data.clipData!!.getItemAt(i).uri
                    imageUriList.add(imageUri)
                }
                if (availableSlots == 0 || data.clipData!!.itemCount > availableSlots) {
                    showToastLong(getString(R.string.feedback_max_image_limit, MAX_IMAGE_COUNT))
                }

            } else if (data?.data != null) {
                val imageUri = data.data
                imageUri?.let {
                    if (imageUriList.size < MAX_IMAGE_COUNT) {
                        imageUriList.add(it)
                    } else {
                        showToastLong(getString(R.string.feedback_max_image_limit))
                    }
                }
            }
            if (imageUriList.size >= 5) {
                mBinding.rlAddPicture.visibility = View.GONE
            }
        }

        imageAdapter?.notifyDataSetChanged()
    }

    override fun onSendFeedBackSuccess(success: Boolean) {
        if (success) {
            showToast(getString(R.string.feedback_send_success))
            finish()
        } else {
            showToast(getString(R.string.feedback_send_failed))
        }
    }

    private fun showPickPictureDialog() {
        val datas = mutableListOf<DoorData>()
        datas.add(DoorData(doorName = getString(R.string.feedback_dialog_pick_camera)))
        datas.add(DoorData(doorName = getString(R.string.feedback_dialog_pick_gallery)))

        val bottomSheetDialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        bottomSheetDialog.setCanceledOnTouchOutside(true)
        val view = LayoutInflater.from(this).inflate(R.layout.bottom_dialog, null, false)
        view.findViewById<TextView>(R.id.center_title).setText(
            R.string.feedback_dialog_add_picture
        )
        val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerView)
        view.findViewById<ImageView>(R.id.image_cancel).setOnClickListener {
            bottomSheetDialog.dismiss()
        }

        val dtmfAdapter = Module_Phone_DtmfAdapter(datas)
        recyclerView.adapter = dtmfAdapter
        recyclerView.addItemDecoration(SpaceItemDecoration(this))

        dtmfAdapter.setOnItemChildClickListener { _, _, position ->
            bottomSheetDialog.dismiss()
            when (position) {
                0 -> {
                    openCamera()
                }

                1 -> {
                    openImagePicker()
                }
            }
        }

        bottomSheetDialog.setContentView(view)
        bottomSheetDialog.show()
    }

    private fun openCamera() {
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        if (intent.resolveActivity(packageManager) != null) {
            // 创建临时文件
            var photoFile: File? = null
            try {
                photoFile = createImageFile()
            } catch (ex: IOException) {
                ex.printStackTrace()
            }
            if (photoFile != null) {
                // 适配Android 7.0+，使用FileProvider
                imageUri = FileProvider.getUriForFile(
                    this,
                    "$packageName.fileprovider",  // 与Manifest中的authorities一致
                    photoFile
                )
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
                startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
            }
        }
    }

    @Throws(IOException::class)
    private fun createImageFile(): File {
        val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        val imageFileName = "CAMERA_" + timeStamp + "_"
        val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        val image = File.createTempFile(imageFileName, ".jpg", storageDir)
        currentPhotoPath = image.absolutePath
        return image
    }

    private fun getRealPathFromURI(uri: Uri): String? {
        val projection = arrayOf(MediaStore.Images.Media.DATA)
        val cursor = contentResolver.query(uri, projection, null, null, null) ?: return null
        val column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
        cursor.moveToFirst()
        val path = cursor.getString(column_index)
        cursor.close()
        return path
    }

}